<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:sqlml ="http://MySQL-DbML.org"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:aorml="http://AOR-AppML.org">
    <xsl:output method="xml" />
    <xsl:output name="sql" method="text" />
    <xsl:variable name="break"><xsl:text>
</xsl:text></xsl:variable>
    <xsl:variable name="tab"><xsl:text>    </xsl:text></xsl:variable>
    <!--path for helium: /srv/www/webapps/oryx/test/ -->
    <!-- path on local windows: file:///Program Files/apache-tomcat6/webapps/oryx/test/ -->
    <xsl:variable name="filepath"><xsl:text></xsl:text></xsl:variable>
    <xsl:function name="aorml:upperFirst" as="xs:string?">
        <xsl:param name="trans" as="xs:string?"></xsl:param>
        <xsl:sequence select="concat(upper-case(substring($trans,1,1)),substring($trans,2))"/>
    </xsl:function>
    <xsl:function name="aorml:lowerFirst" as="xs:string?">
        <xsl:param name="trans" as="xs:string?"></xsl:param>
        <xsl:sequence select="concat(lower-case(substring($trans,1,1)),substring($trans,2))"/>
    </xsl:function>
    <xsl:template match="/">
        <xsl:call-template name="generateSQL" />
    </xsl:template>  
    
    <xsl:template name="generateSQL">
        <xsl:result-document href="{$filepath}zf-my.sql" format="sql">
            <xsl:for-each select="//sqlml:ObjectTable">
                <xsl:sort select="sqlml:ForeignKey"></xsl:sort>
                <xsl:text>CREATE TABLE IF NOT EXISTS `</xsl:text>
                <xsl:value-of select="@name"></xsl:value-of>
                <xsl:text>`(</xsl:text>
                <xsl:for-each select="sqlml:Attribute">
                    <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                    <xsl:text>`</xsl:text>
                    <xsl:value-of select="@name"></xsl:value-of>
                    <xsl:text>` </xsl:text>
                    <xsl:if test="not(contains(@type, ' '))">
                        <xsl:value-of select="@type"></xsl:value-of>
                        <xsl:if test="@type='VARCHAR'">
                            <xsl:text>(</xsl:text>
                            <xsl:value-of select="@typeSize"></xsl:value-of>
                            <xsl:if test="not(@typeSize)">
                                <xsl:text>100</xsl:text>
                            </xsl:if>
                            <xsl:text>)</xsl:text>
                        </xsl:if>
                        <xsl:if test="@type='INT'">
                            <xsl:text>(</xsl:text>
                            <xsl:value-of select="@typeSize"></xsl:value-of>
                            <xsl:if test="not(@typeSize)">
                                <xsl:text>10</xsl:text>
                            </xsl:if>
                            <xsl:text>)</xsl:text>
                        </xsl:if>
                    </xsl:if>
                    <xsl:if test="contains(@type, ' ')">
                        <xsl:text> ENUM(</xsl:text>
                        <xsl:for-each select="tokenize(@type, ' ')">
                            <xsl:text>'</xsl:text>
                            <xsl:value-of select="."></xsl:value-of>
                            <xsl:text>'</xsl:text>
                            <xsl:if test="position() != last()">                        
                                <xsl:text>, </xsl:text>
                            </xsl:if>  
                        </xsl:for-each>
                        <xsl:text>)</xsl:text>  
                    </xsl:if>
                    <xsl:if test="@isMandatory = 'true'">
                        <xsl:text> NOT NULL</xsl:text>
                    </xsl:if>
                    <xsl:if test="position() != last()">                        
                        <xsl:text>, </xsl:text>
                    </xsl:if>                    
                </xsl:for-each>
                <xsl:if test="sqlml:Attribute[@isPrimaryKey='true']">
                <xsl:text>,</xsl:text>
                <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                    <xsl:text>PRIMARY KEY(</xsl:text>
                    <xsl:for-each select="sqlml:Attribute[@isPrimaryKey='true']">
                        <xsl:text>`</xsl:text>
                        <xsl:value-of select="@name"></xsl:value-of>
                        <xsl:text>`</xsl:text>
                        <xsl:if test="position() != last()">
                            <xsl:text>, </xsl:text>
                        </xsl:if>
                    </xsl:for-each>
                    <xsl:text>)</xsl:text>
                </xsl:if>                
                <xsl:for-each select="sqlml:ForeignKey">
                    <xsl:text>,</xsl:text>
                    <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                    <xsl:text>FOREIGN KEY (`</xsl:text>
                    <xsl:value-of select="@foreignKeyAttribute"></xsl:value-of>
                    <xsl:text>`) REFERENCES `</xsl:text>
                    <xsl:value-of select="@referencedTable"></xsl:value-of>
                    <xsl:text>` (`</xsl:text>
                    <xsl:value-of select="@referencedAttribute"></xsl:value-of>
                    <xsl:text>`) ON DELETE CASCADE ON UPDATE CASCADE</xsl:text>
                </xsl:for-each>
                <xsl:for-each select="sqlml:Attribute">
                    <xsl:if test="@minValue">
                        <xsl:text>,</xsl:text>
                        <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                        <xsl:text>CHECK(`</xsl:text>
                        <xsl:value-of select="@name" />
                        <xsl:text>` >= </xsl:text>
                        <xsl:value-of select="@minValue" />
                        <xsl:text>)</xsl:text>
                    </xsl:if>
                    <xsl:if test="@maxValue">
                        <xsl:text>,</xsl:text>
                        <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                        <xsl:text>CHECK(`</xsl:text>
                        <xsl:value-of select="@name" />
                        <xsl:text>` &lt;= </xsl:text>
                        <xsl:value-of select="@maxValue" />
                        <xsl:text>)</xsl:text>
                    </xsl:if>
                </xsl:for-each>
                <xsl:value-of select="$break"></xsl:value-of>
                <xsl:text>) ENGINE=INNODB;</xsl:text>
                <xsl:value-of select="concat($break,$break)"></xsl:value-of>
            </xsl:for-each>
            <!-- Tables from AssociationTable -->
            <xsl:for-each select="//sqlml:AssociationTable">
                <xsl:text>CREATE TABLE IF NOT EXISTS `</xsl:text>
                <xsl:value-of select="@name"></xsl:value-of>
                <xsl:text>`(</xsl:text>
                <xsl:for-each select="sqlml:Attribute">
                    <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                    <xsl:text>`</xsl:text>
                    <xsl:value-of select="@name"></xsl:value-of>
                    <xsl:text>` </xsl:text>
                    <xsl:value-of select="@type"></xsl:value-of>
                    <xsl:if test="@type='VARCHAR'">
                        <xsl:text>(</xsl:text>
                        <xsl:value-of select="@typeSize"></xsl:value-of>
                        <xsl:if test="not(@typeSize)">
                            <xsl:text>100</xsl:text>
                        </xsl:if>
                        <xsl:text>)</xsl:text>
                    </xsl:if>
                    <xsl:if test="@type='INT'">
                        <xsl:text>(</xsl:text>
                        <xsl:value-of select="@typeSize"></xsl:value-of>
                        <xsl:if test="not(@typeSize)">
                            <xsl:text>10</xsl:text>
                        </xsl:if>
                        <xsl:text>)</xsl:text>
                    </xsl:if>   
                    <xsl:text> NOT NULL</xsl:text>
                    <xsl:if test="position() != last()">
                        <xsl:text>, </xsl:text>
                    </xsl:if>
                </xsl:for-each>
                <xsl:text>,</xsl:text>
                <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                <xsl:text>PRIMARY KEY(</xsl:text>
                <xsl:for-each select="sqlml:Attribute">
                    <xsl:text>`</xsl:text>
                    <xsl:value-of select="@name"></xsl:value-of>
                    <xsl:text>`</xsl:text>
                    <xsl:if test="position() != last()">
                        <xsl:text>, </xsl:text>
                    </xsl:if>
                </xsl:for-each>
                <xsl:text>),</xsl:text>
                <xsl:for-each select="sqlml:ForeignKey">
                    <xsl:value-of select="concat($break,$tab)"></xsl:value-of>
                    <xsl:text>FOREIGN KEY (`</xsl:text>
                    <xsl:value-of select="@foreignKeyAttribute"></xsl:value-of>
                    <xsl:text>`) REFERENCES `</xsl:text>
                    <xsl:value-of select="@referencedTable"></xsl:value-of>
                    <xsl:text>` (`</xsl:text>
                    <xsl:value-of select="@referencedAttribute"></xsl:value-of>
                    <xsl:text>`)ON DELETE CASCADE ON UPDATE CASCADE</xsl:text>
                    <xsl:if test="position() != last()">
                        <xsl:text>, </xsl:text>
                    </xsl:if>
                </xsl:for-each>
                <xsl:value-of select="$break"></xsl:value-of>
                <xsl:text>) ENGINE=INNODB;</xsl:text>
                <xsl:value-of select="concat($break,$break)"></xsl:value-of>
            </xsl:for-each>
        </xsl:result-document>
    </xsl:template>
</xsl:stylesheet>